//
//  ST_OneLineBarrageView.swift
//  BTVideo
//
//  Created by DouLei on 2019/7/16.
//  Copyright © 2019 DouLei. All rights reserved.
//

import UIKit
import SnapKit
import SwifterSwift
import SwiftyAttributes



struct ST_FWBarrageItemModel {
    
    var attributedStr:NSAttributedString
    
    var size:CGSize
    
    var vip = false
//    可变速度
    var speed = ScreenWidth/10.0/30.0
    
    var userAvatar:String?
    
    var backgroundColor:UIColor?
}

class ST_OneLineBarrageView: UIView {
    
    
    
//    MARK: - init
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.clipsToBounds = true
        
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
//    MARK: - set up Data
    var data_array = [ST_FWBarrageItemModel]()
    
    /// 循环播放弹幕
    var is_loop_play = true
    
    var background_color_alpha = 0.3.cgFloat
    
    private var displaying_labels = [ST_OneLineBarrageLabel]()
    
    private var displaying_rich_labels = [ST_OneLineBarrageRichLabel]()
    
    private var cache_labels = Set<ST_OneLineBarrageLabel>()
    
    private var cache_rich_labels = Set<ST_OneLineBarrageRichLabel>()
    
    
    private let gap = 17.cgFloat
    
    private var displayLink:CADisplayLink?
    
    
    
    
//    MARK: - Moving
    var will_append_idx = 0
    
    @objc func moving(){
        
        var willMove = Set<ST_OneLineBarrageLabel>()
        
        var willMoveRich = Set<ST_OneLineBarrageRichLabel>()

        for label in displaying_labels {
            let moveToX = label.x - label.model.speed
//        will cache label , move to the outside of screen
            if moveToX + label.width < -20 {
                willMove.update(with: label)
            }else{
//        moving  displaying label
                label.x = moveToX
//                print("Move To --",moveToX)
            }
        }
        
        
        for label in displaying_rich_labels {
            let moveToX = label.x - label.model.speed
//        will cache label , move to the outside of screen
            if moveToX + label.width < -20 {
                willMoveRich.update(with: label)
            }else{
//        moving  displaying label
                label.x = moveToX
//                print("Move To --",moveToX)
            }
        }
        
        
//        remove label
        for item in willMove {
            displaying_labels.removeAll(item)
            item.removeFromSuperview()
        }
        
        for item in willMoveRich {
            displaying_rich_labels.removeAll(item)
            item.removeFromSuperview()
        }
        
//        cache label
        cache_labels.formUnion(willMove)
        
        cache_rich_labels.formUnion(willMoveRich)
        
//       check  need add new Label
        var needAddNewLabel = true
        
        if let last = displaying_labels.last,last.frame.maxX > ScreenWidth{
            needAddNewLabel = false
        }
        if let last = displaying_rich_labels.last,last.frame.maxX > ScreenWidth{
            needAddNewLabel = false
        }
        
        if !needAddNewLabel{
            return
        }
        
//        弹幕加载完毕 或 报错
        guard let model = data_array[safe:will_append_idx] else {
            
            if displaying_labels.count == 0 && displaying_rich_labels.count == 0{
                self.stop()
            }
            
//            当前只有一个展示
            if displaying_labels.count == 1 || displaying_rich_labels.count == 1{
                
                var firstMax = displaying_labels.first?.frame.maxX ?? 1
                
                let richMax = displaying_rich_labels.first?.frame.maxX ?? 1
                
                if richMax < firstMax{
                    firstMax = richMax
                }
                
                if firstMax <= 0 {
//                    will_append_idx = 0
                    
                    self.stop()
                }
            }
//            if let first = displaying_labels.first,displaying_labels.count == 1 ,first.frame.maxX <= 0{
//
//                will_append_idx = 0
//            }
            return
        }
        
//        if model.backgroundColor != nil {
            
            add_rich_label(model: model)
            
//        }else{
//
//            add_normal_label(model: model)
//        }
        
    }
    
    private func add_normal_label(model:ST_FWBarrageItemModel){
        
        var appendLabel:ST_OneLineBarrageLabel!
        if cache_labels.count > 0{
            let label = cache_labels.removeFirst()
            appendLabel = label
        }else{
            appendLabel = ST_OneLineBarrageLabel()
        }
        
        appendLabel.frame = CGRect.init(x: gap + ScreenWidth, y: 0, width: model.size.width, height: model.size.height)
        
        appendLabel.model = model
        
        displaying_labels.append(appendLabel)
        
        self.addSubview(appendLabel)
        
        will_append_idx += 1
        
    }
    
    
    private func add_rich_label(model:ST_FWBarrageItemModel){
        
        var appendLabel:ST_OneLineBarrageRichLabel!
        if cache_rich_labels.count > 0{
            let label = cache_rich_labels.removeFirst()
            appendLabel = label
        }else{
            appendLabel = ST_OneLineBarrageRichLabel()
        }
        
        appendLabel.frame = CGRect.init(x: gap + ScreenWidth, y: 0, width: model.size.width, height: model.size.height)
        
        appendLabel.model = model
        
        appendLabel.backcolorView.alpha = self.background_color_alpha
        
        displaying_rich_labels.append(appendLabel)
        
        self.addSubview(appendLabel)
        
        will_append_idx += 1
        
    }
    
//    MARK: - Public Method
    func play(){
        
        self.stop()
        
        self.will_append_idx = 0
        
        self.displayLink = CADisplayLink.init(target: self, selector: #selector(moving))
        
        self.displayLink?.add(to: RunLoop.current, forMode: RunLoop.Mode.common)
        
    }
    
    func stop(){
        
        self.displayLink?.invalidate()
        self.displayLink = nil
        
        self.will_append_idx = 0
        
        for item in displaying_labels {
            item.removeFromSuperview()
            cache_labels.update(with: item)
        }
        
        displaying_labels.removeAll()
        
        for item in displaying_rich_labels {
            item.removeFromSuperview()
            cache_rich_labels.update(with: item)
        }
        
        displaying_rich_labels.removeAll()
        
//        self.data_array.removeAll()
        
    }
    
    func out_side_stop()  {
        self.stop()
        self.data_array.removeAll()
    }
    
    /**
     暂定 自己发弹幕调用
     */
    func insert(barrage:ST_BarrageModel)  {
        
        
        let m = ST_CompatibilityBarrageItem(item: barrage)
        
        if self.displayLink != nil{
            
            print("插入弹幕idx:\(will_append_idx.string)")
            
            data_array.insert(m, at: will_append_idx)
            
        }else{
            
            print("插入弹幕重新开始\(data_array.count)")
            
            if is_loop_play{
                data_array.append(m)
            }else{
                data_array = [m]
            }
            
            
            self.play()
        }
        
    }
    
}



//MARK: - Override Label
class ST_OneLineBarrageLabel: UIView {
    
    var model:ST_FWBarrageItemModel!{
        didSet{
            content_label.attributedText = model.attributedStr
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        addSubview(content_label)
        
        content_label.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    lazy var content_label:UILabel = {
        let control = UILabel.init()
        return control
    }()
}




class ST_OneLineBarrageRichLabel: UIView {
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        addSubview(backcolorView)
        addSubview(cover_image_view)
        addSubview(vipSignImageView)
        addSubview(content_label)
        
        backcolorView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        cover_image_view.snp.makeConstraints { (make) in
            make.top.left.equalToSuperview().offset(2)
            make.bottom.equalToSuperview().offset(-2)
            make.width.equalTo(cover_image_view.snp.height)
        }
        
        vipSignImageView.snp.makeConstraints { (make) in
            make.bottom.equalTo(cover_image_view)
            make.right.equalTo(cover_image_view).offset(3)
            make.width.height.equalTo(12)
        }
        
        content_label.snp.makeConstraints { (make) in
            make.right.bottom.top.equalToSuperview()
            make.left.equalTo(cover_image_view.snp.right).offset(5)
        }
        
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    lazy var content_label:UILabel = {
        let control = UILabel.init()
        return control
    }()

    lazy var cover_image_view:UIImageView = {
        let control = UIImageView()
        control.contentMode = UIView.ContentMode.scaleAspectFill
        control.cornerRadius = (barrageLabelHeight-4)/2.0
//        control.borderColor = Color.white
//        control.borderWidth = 1
        return control
    }()
    
    lazy var vipSignImageView:UIImageView = {
        let control = UIImageView()
        control.image = ST_ImageUtils.imageName("首页_icon_会员_small")
        return control
    }()
    
    lazy var backcolorView:UIView = {
       let control = UIView()
        control.cornerRadius = 13
        control.alpha = 0.6
        return control
    }()
    
    
    var model:ST_FWBarrageItemModel!{
        didSet{
         
            
            cover_image_view.pin_setImage(from: model.userAvatar?.compress_image().url, placeholderImage: ST_SwiftConst.shared.fetch_random_place_holder_image())
            
            content_label.attributedText = model.attributedStr
            
            backcolorView.backgroundColor = model.backgroundColor
            
            vipSignImageView.isHidden = !model.vip
        }
    }
}
